/* Copyright  All rights reserved. */
enyo.kind({
	name: "com.rextoy.HudsonView",
	kind: enyo.VFlexBox,
	components: [
		// Web Services
        {
            name: "getApps", 
			kind: "WebService",
            method: "GET",
            handleAs: "json",
            onSuccess: "getAppListSuccess",
            onFailure: "getAppListFailure"
        },
		
		{
            name: "getDetail", 
			kind: "WebService",
            method: "GET",
            handleAs: "json",
            onSuccess: "getAppDetailSuccess",
            onFailure: "getAppDetailFailure"
        },
		
		{
            name: "getBuild", 
			kind: "WebService",
            method: "GET",
            handleAs: "json",
            onSuccess: "getBuildDetailSuccess",
            onFailure: "getBuildDetailFailure"
        },
		
		{
            name: "runBuild", 
			kind: "WebService",
            method: "POST",
            handleAs: "json",
			onSuccess: "runBuildSuccess",
			onFailure: "runBuildFailure"
        },
		
		{
            name: "switchJob", 
			kind: "WebService",
            method: "POST",
            handleAs: "json",
			onSuccess: "switchJobSuccess",
			onFailure: "switchJobFailure"
        },
		
		//UI
		{ kind: "Popup", name: "scheduleSuccess", modal: true, style: "width: 600px;", components: [
				{ kind: "RowGroup", components: [
						{ content: "A build is scheduled successfully, it may take some time to finish. Please come back later."}
					]
				},
				
				{ kind: "HFlexBox", pack: "end", components: [
						{kind: "Button", caption: "OK", onclick: "scheduleOKClick", style: "margin-right: 10px;"}
					]
				}
			]
		},
		
		{ kind: "Popup", name: "addServerDialog", lazy: false, scrim: true, modal: true, style: "width: 600px;", components: [
			{kind: "RowGroup", components: [
				{name: "addServerUrl", value:"http://", inputClassName: "richy", richContent: false, kind: "RichText", components: [
					{style: "color: #1F75BF; font-size: 13px;", content: "hudson server url"}
				]},
				{name: "username", value:"", inputClassName: "richy", richContent: false, kind: "RichText", components: [
					{style: "color: #1F75BF; font-size: 13px;", content: "username"}
				]},
				{name: "password", value:"", inputClassName: "richy", richContent: false, kind: "PasswordInput", components: [
					{style: "color: #1F75BF; font-size: 13px;", content: "password"}
				]}				
			]},
			{content: "Leave username/password blank if server allow anonymous access.", style: "color: #1F75BF; font-size: 13px;"},
			{kind: "HFlexBox", pack: "end", components: [
				{kind: "Button", caption: "OK", onclick: "okAddClick", style: "margin-right: 10px;"},
				{kind: "Button", caption: "Cancel", onclick: "cancelAddClick"}
			]}
		]},
		
		{ kind: "PageHeader", 
				components:[
						{ content: "Hudson View" },
						{ kind: "Spacer"},
						{ kind: "Button", name: "btnServerList", className: "enyo-button-affirmative", caption: "Manage Server List", onclick: "manageServerList", toggling: true }
				]
		},
    	{ kind: "HFlexBox", name:"consoleGroup", style: "height: 40px;color: white; background-color: gray; padding: 4px; border: 1px solid black; font-size: 14px;",
				components:[						
						{name: "console", content:'', flex: 1},
						{kind: "Spacer"},
						{kind: "Spinner", name:"spinner"},
				]		
		},		
		{ kind: "RowGroup", name:"serverGroup", caption: "Hudson Server", 
				components: [{ kind: "HFlexBox", 
										components: [
											{ kind: "ListSelector", label: "Select Hudson server from list", flex: 1, name: "hudsonServer" },
											
											{ kind: "Button", caption: "List Applications", className: "enyo-button-blue", onclick: "showAppsClick" }											
										]
							}]
        },
        
		{ kind: "SlidingPane", name: "slidingPane", flex: 1, 
				components: [
								{ kind: "SlidingView", name: "left", width: "400px", 
										components: [
														{ kind: "Header", content: "Applications", style:"height:70px"},
														{ kind: "Scroller", name: "appScroller", flex: 1, 
																components: [{kind: "VirtualList", name: "appList", flex: 1, onSetupRow: "appListSetupRow", 
																						components: [{ kind: "Item", name: "appItem", layoutKind: "HFlexLayout",
																												components: [
																																{ kind: "Image", name: "appImg" },
																																{ name: "itemName", flex: 1, onclick: "applistItemClick" }																																
																															]
																									}]
																			}]
														},
														{ kind: "Toolbar", 
																components: [{ kind: "GrabButton" }]
														}
													]
								},
								{ kind: "SlidingView", name: "middle", width: "320px", flex: 1, peekWidth: 50, 
										components: [
														{ kind: "Header", name: "ApplicationDetail", 
																components: [
																				{ content: "Detail", flex:1},
																				{ kind: "ToggleButton", name: "jobStatus", onLabel:"Enable", offLabel:"Disable", onChange: "toggleJobClick", disabled: true},
																				{ kind: "Button",name: "build", caption: "Schedule Build", onclick: "BuildAppClick"},
																			]
														},
														{ kind: "Scroller", name:"detailScroller", flex: 1, 
																components: [{kind: "VirtualList", name: "appDetail", flex: 1, onSetupRow: "detailListSetupRow", 
																					components: [
																									{ kind: "Divider", name: "divider" },
																									{ kind: "Item", 
																											components: [																																
																															{ name: "detailItem", flex: 1}																																
																														]
																									}
																								]
																			}]
														},
														{ kind: "Toolbar", 
																components: [
																				{ kind: "GrabButton" }
																			]
														}
													]
								},
								{ kind: "SlidingView", name: "right", dragAnywhere: false, lazy: true, flex: 1,
										components: [
												{ kind: "Header", 
													components: [
																	{ content: "Server List", flex: 1} ,
																	{ kind: "Button", caption: "Add Server", className: "enyo-button-blue", onclick: "addServerClick" }
																]
												},
												{ kind: "Scroller", flex: 1, 
																components: [{kind: "VirtualList", name: "serverList", onSetupRow: "serverListSetupRow",
																						components: [{ kind: "SwipeableItem", name: "serverItem", layoutKind: "HFlexLayout", onConfirm: "deleteServer",
																												components: [
																																{name: "serverItemName"},
																																{kind: "Spacer"},
																																{name: "serverItemValue"},
																																{kind: "Spacer"}
																															]
																									}]
																			}]
														},
												{ kind: "Toolbar", 
																components: [
																				//{ kind: "GrabButton" }
																			]
												}
										]
								}
							]
		}			
	],
	
	create: function () {
        // calling base class constructor
        this.inherited(arguments);
		
		this.$.build.disabled = true;
		this.$.build.applyStyle("color", "gray");
        
        //this.$.hudsonServer.setValue(this.server);

		this.applications = [];
		this.health = [];
		
		var str = enyo.getCookie("servers");
		if(str !== undefined)
			this.servers = enyo.json.parse( str );
		else
			this.servers = [];
			
		this.refreshServerListSelector();
    },
	
	makeBasicAuth: function(user, password) {
		var token = user + ':' + password;
		var hash = enyo.string.toBase64(token);
		return "Basic " + hash;
	},
	
	refreshServerListSelector: function() {
		this.log("=============server list refresh. length = " + this.servers.length);
		var arr = [];
		for(var i = 0; i < this.servers.length; i++) {
			var record = this.servers[i]
			arr.push({caption: record.url, value: record});
		}
		
		this.$.hudsonServer.setItems(arr);
	},
	
	setConsoleStartAsyncCall: function(msg) {
		this.$.spinner.setShowing(true);
		if(msg==null)
			this.$.console.setContent("Contacting server...");
		else
			this.$.console.setContent(msg);
	},
	
	setConsoleStopAsyncCall: function(msg) {
		this.$.spinner.setShowing(false);
		this.$.console.setContent(msg);
	},
	
	getAppListSuccess: function(inSender, inResponse) {		
		if(inResponse==""){
			this.setConsoleStopAsyncCall("Get app list fail.");
			return;
		}
		
		this.setConsoleStopAsyncCall("Received successfully.");
		
		var res = inResponse;
		//this.log(enyo.json.stringify(res.jobs));
		
		this.applications = res.jobs;
		this.$.appList.refresh();
	},
	
	getAppListFailure: function(inSender, inResponse) {
		this.setConsoleStopAsyncCall("Get app list fail. Please try again later");
		
		this.applications = [];		
		
		this.$.appList.refresh();
		this.$.appList.punt();
		this.health = [];
		
		this.$.appDetail.refresh();
		this.$.appDetail.punt();
	},
	
	serverListSetupRow: function(inSender, inIndex) {
		var record = this.servers[inIndex];
		if(record){
			this.$.serverItemValue.setContent(record.url);
			return true;
		}
	},
	
	detailListSetupRow: function(inSender, inIndex) {		
		var record = this.health[inIndex];
		
		if(record){
			if(record.description)
			{				
				this.$.divider.setCaption("App Summary(Latest build)");
				this.$.divider.canGenerate = (inIndex == 0);
				this.$.detailItem.setContent(record.description);
			}
			else
			{
				if(record.actions) {
					var status = (!!record.result) ? record.result : null;
					if(record.building) status = '[building in progress]';
					this.$.divider.setCaption("Build#" + record.number + "---" + status);
					this.$.divider.canGenerate = true;
					this.$.detailItem.setContent("");
				} else {
					this.$.divider.canGenerate = false;					
					this.$.detailItem.setContent(record);
				}
			}
			return true;
		}
		return false;
	},
	
	getAppDetailSuccess: function(inSender, inResponse) {
		this.resDetail = inResponse;
		
		this.setControlStatus(inResponse.buildable);
		this.health = inResponse.healthReport;
		
		//this.log(enyo.json.stringify(inResponse.healthReport));
		this.$.appDetail.punt();
		
		if(!! inResponse.queueItem){
			this.health.push({description: inResponse.queueItem.why});
		}		
		
		this.buildInfoLength = Math.min(5, inResponse.builds.length);
		
		this.gotBuildNumber = 0;
		if(this.buildInfoLength > 0) {
			this.getBuildNumberDetail();
		} else {
			this.$.appDetail.refresh();
			this.setConsoleStopAsyncCall("Get application detail Success.");
		}
	},
	
	getBuildDetailSuccess: function(inSender, inResponse) {
		this.setConsoleStopAsyncCall("Get application detail Success.");
		this.gotBuildNumber++;
		
		var record = inResponse;
		this.health.push(record);
		
		//this.log(enyo.json.stringify(record));
		
		//Note:get start by information
		var found = false;
		var startBy;
		for(var i = 0; i < record.actions.length; i++) {
			for(var j = 0; j <= record.actions[i].causes.length; j++) {
				startBy = record.actions[i].causes[j].shortDescription;
				if(!!startBy) {					
					found = true;
					break;
				}
			}
			if(found) break;
		}		
		if(!startBy) startBy = 'Start';
		
		var s = startBy + ' at ' + record.id + ' [Duration]: ' + record.duration;
		this.health.push(s);
		
		for(var i = 0; i < record.changeSet.items.length; i++) {				
			var m = record.changeSet.items[i];
			var str = '[Time]: ' + m.date + ' [Revision]: ' + m.revision + ' [Message]:' + m.msg + ' [User]:' + m.user;
			this.health.push(str);
		}
		
		if(this.gotBuildNumber<this.buildInfoLength)
			this.getBuildNumberDetail();
		
		this.$.appDetail.refresh();
	},
	
	getBuildNumberDetail: function(){
		var url = this.resDetail.builds[this.gotBuildNumber].url;
			
		this.$.getBuild.setHeaders({ accept: "application/json" });
		this.$.getBuild.setUrl(url + 'api/json?depth=1');
		this.$.getBuild.call();
		this.setConsoleStartAsyncCall();
	},	
	
	setControlStatus: function(enable){
		this.$.jobStatus.setState(enable);
		if(enable) {
			this.$.build.applyStyle("color", null);
		} else {			
			this.$.build.applyStyle("color", "white");
		}
		this.$.build.disabled = (!enable);
	},
	
	showAppsClick: function () {
        var svr = this.$.hudsonServer.getValue();
		this.log("====================Get list from server at " + enyo.json.stringify(svr));
		
		//TODO:refactor - extract method with near line 258
		this.health = [];
		this.$.appDetail.punt();
		this.$.appDetail.refresh();
		this.applications = [];
		this.$.appList.punt();
		this.$.appList.refresh();
		
        this.$.getApps.setHeaders({ accept: "application/json" });
		if(svr.usr != "")//Note:Basic Auth
			this.$.getApps.setHeaders({ Authorization: this.makeBasicAuth(svr.usr,svr.pwd)});
		
        this.setConsoleStartAsyncCall();
		this.$.getApps.setUrl(svr.url + 'api/json?depth=1');
		this.$.getApps.call();
		
		this.$.jobStatus.disabled = true;		
    },
	
	appListSetupRow: function(inSender, inIndex) {
		var isRowSelected = (inIndex == this.selectedRow);
		if(isRowSelected){
			this.$.appItem.applyStyle("background", 'silver');
		} else {			
			this.$.appItem.applyStyle("background", 'null');
		}
	
		var record = this.applications[inIndex];
        if (record) {
            this.$.itemName.setContent(record.name);
			//this.log("--------------------" + enyo.json.stringify(record.healthReport));
			//Note:use lowest score and give icon
			var score = 100;
			var lowest = {iconUrl: "health-80plus.gif"};
			for(var i = 0; i < record.healthReport.length; i++) {
				var hReport = record.healthReport[i];
				if( hReport.score < score ) {
					score = hReport.score;
					lowest = hReport;
				}
			}
				
			this.$.appImg.setSrc('Images/' + lowest.iconUrl);
            return true;
        }
        return false;	
	},
	
	applistItemClick: function(inSender, inEvent) {
		this.setConsoleStartAsyncCall();
		this.selectedRow = inEvent.rowIndex;
		var dataClicked = this.applications[inEvent.rowIndex];
		var url = dataClicked.url;
		this.$.getDetail.setHeaders({ accept: "application/json" });
		this.$.getDetail.setUrl(url + 'api/json');
		this.$.getDetail.call();
		
		this.$.jobStatus.disabled = false;		
		this.$.appList.refresh();
	},
	
	BuildAppClick: function() {
		var app = this.applications[this.selectedRow];
		var url = app.url;
		
		this.$.runBuild.setUrl(url + 'build');
		this.$.runBuild.call();
		
		this.$.build.applyStyle("color", "white");
		this.$.build.disabled = true;
	},
	
	toggleJobClick: function(inSender) {
		var app = this.applications[this.selectedRow];
		
		var url = app.url + (inSender.state?'enable':'disable');
		this.$.switchJob.setUrl(url);
		
		this.setConsoleStartAsyncCall();
		this.$.switchJob.call();
	},
	
	switchJobSuccess: function(inSender, inResponse) {
		this.setConsoleStopAsyncCall("Status changed to " + ((this.$.jobStatus.state)?"Enable.":"Disable."));
		this.setControlStatus(this.$.jobStatus.state);
	},
	
	switchJobFailure: function(inSender, inResponse, inRequest) {
		this.log(inRequest.xhr.status);
		if(inRequest.xhr.status == 403) {
			this.setConsoleStopAsyncCall("Status change failed. You don't have permission.");
		} else {
			this.setConsoleStopAsyncCall("Status change failed. Please try again later.");
		}
		this.setControlStatus(!(this.$.jobStatus.state));
	},
	
	manageServerList : function() {
		this.log("====================Hide server list");
		if(this.$.btnServerList.depressed) {
			this.$.consoleGroup.setShowing(false);
			this.$.serverGroup.setShowing(false);
			this.$.slidingPane.selectViewByName("right");
			this.$.right.setShowing(true);
			this.$.serverList.refresh();
			this.$.btnServerList.setCaption("Back to Main View");
		} else {			
			this.$.consoleGroup.setShowing(true);
			this.$.serverGroup.setShowing(true);
			this.$.right.setShowing(false);
			this.$.slidingPane.selectViewByName("left");
			this.$.btnServerList.setCaption("Manage Server List");
		}
	},
	
	runBuildSuccess: function() {		
		this.$.scheduleSuccess.openAtCenter();
	},
	
	runBuildFailure: function(inSender, inResponse, inRequest) {
		this.log(inRequest.xhr.status);
		if(inRequest.xhr.status==403) {
			this.setConsoleStopAsyncCall("Failed. You don't have permission.");
		} else {
			this.setConsoleStopAsyncCall("Failed. Please try again later.");
		}		
		
		this.$.build.applyStyle("color", null);
		this.$.build.disabled = false;
	},
	
	deleteServer: function(inSender, inIndex) {
		this.servers.splice(inIndex, 1);		
		this.$.serverList.refresh();
		enyo.setCookie("servers", enyo.json.stringify(this.servers));
		this.refreshServerListSelector();
	},
	
	addServerClick: function() {
		this.$.addServerDialog.openAtCenter();
		this.$.addServerUrl.setValue("http://");
		this.$.username.setValue("");
		this.$.password.setValue("");
	},
	
	okAddClick: function() {
		var newUrl = this.$.addServerUrl.getValue();
		if(newUrl.charAt(newUrl.length - 1)!='/')
			newUrl = newUrl+'/';
		
		var newUser = this.$.username.getValue();
		var newPwd = this.$.password.getValue();
		this.servers.push({url: newUrl, usr:newUser, pwd: newPwd});
		this.$.serverList.refresh();
		enyo.setCookie("servers", enyo.json.stringify(this.servers));
		
		this.refreshServerListSelector();
		this.$.addServerDialog.close();
	},
	
	cancelAddClick: function() {
		this.$.addServerDialog.close();
	},
	
	scheduleOKClick: function() {
		this.$.scheduleSuccess.close();
	}
});